package Game;

import java.awt.BorderLayout;

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.swing.JFrame;

import com.jogamp.newt.event.KeyEvent;

import Physics.CollisionPlane;
import Physics.CollisionPrimitive;
import Physics.Gravity;
import Physics.PhysicsEngine;
import Physics.Vector3;

/**
 * Main Furious Tourist game application. Extends from
 * GameApp which gives us the ability to call update,
 * render and gather input every iteration.
 */
public class FuriousTourist extends GameApp 
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	
	public static void main(String[] args) {
        GLCapabilities capabilities = createGLCapabilities();
        FuriousTourist canvas = new FuriousTourist(capabilities, 1280, 720);
        JFrame frame = new JFrame("Mini JOGL Demo");
        frame.getContentPane().add(canvas, BorderLayout.CENTER);
        frame.setSize(1280, 720);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        canvas.requestFocus();
    }
	
	//////////////////////////////
	// Member Variables
	//////////////////////////////
	PhysicsEngine m_physics;
	InputHandler m_input;
	
	Sphere 	m_sphere;
	Box		m_box1;
	Box		m_box2;
	
	//////////////////////////////
	// Member functions
	//////////////////////////////
	public FuriousTourist(GLCapabilities capabilities, int width, int height)
	{
		// call the super class constructor
		super(capabilities, width, height);
		m_input = new InputHandler();
		addKeyListener(m_input);
		addMouseListener(m_input);
		addMouseMotionListener(m_input);
	}
	
	//////////////////////////////
	// GameApp implementation
	//////////////////////////////	
	@Override
	void render(GLAutoDrawable drawable) {
		
		GL2 gl = drawable.getGL().getGL2();

        // fixed this to also clear the depth buffer.
        gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);

        setCamera(gl, m_glu, 60);
            	
        m_sphere.render(gl, m_glu);
        m_box1.render(gl, m_glu);
        m_box2.render(gl, m_glu);
		
	}

	@Override
	void gameInit() {
		// initialize the physics engine
		m_physics = new PhysicsEngine(100, 100);
		
		// create a sphere and add it to the physics engine
		m_sphere = new Sphere(1.0f, ObjectMaterial.COCONUT, ObjectType.WEAPON_NORMAL);
		m_sphere.m_body.setPosition(new Vector3(0.0f, 20.0f, 0.0f));
		m_physics.addObject((CollisionPrimitive)m_sphere);
		
		// create a couple of boxes and add them to the physics engine
		m_box1 = new Box(4.0f, 4.0f, 3.0f, ObjectMaterial.DEFAULT);
		m_box1.m_body.setPosition(new Vector3(-25.0f, 10.0f, 0.0f));
		m_physics.addObject((CollisionPrimitive)m_box1);
		m_box2 = new Box(4.0f, 4.0f, 3.0f, ObjectMaterial.DEFAULT);
		m_box2.m_body.setPosition(new Vector3(+25.0f, 20.0f, 0.0f));
		m_physics.addObject((CollisionPrimitive)m_box2);
		
		// add a gravity vector to the list of global forces (forces which affect everything)		
		Vector3 gravity = new Vector3(0.0f, -30.0f, 0.0f);
		Gravity force = new Gravity(gravity);
		m_physics.m_globalRegistry.add(force);
		
		// add a ground plane
		CollisionPlane ground = new CollisionPlane();
		ground.m_direction = new Vector3(0, 1, 0);
		ground.m_distance = 0.0f;
		m_physics.addObject((CollisionPrimitive)ground);
		
		m_physics.endFrame();
	}
	
	protected void update() {
		
		Vector3 vel = new Vector3(0.0f, 0.0f, 0.0f);
		boolean moved = false;
		
		if(m_input.key[KeyEvent.VK_W])
		{
			vel.addAndSet(new Vector3(0.0f, 80.0f, 0.0f));
			moved = true;
		}
		
		if(m_input.key[KeyEvent.VK_A])
		{
			vel.addAndSet(new Vector3(-40.0f, 0.0f, 0.0f));
			moved = true;
		}
		
		if (m_input.key[KeyEvent.VK_D])
		{
			vel.addAndSet(new Vector3(40.0f, 0.0f, 0.0f));
			moved = true;
		}
		
		if(moved)
		{
			m_sphere.m_body.setVelocity(vel);
			m_sphere.m_body.setAcceleration(new Vector3(0.0f, 0.0f, 0.0f));
		}
		
    	m_physics.update(0.01f);
    }
	
}
